package com.sunshine.lnuplus.utils;

import com.sunshine.lnuplus.model.QingGuoUserBean;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Created by GangJust
 * 该代码已经向作者授权
 * 源代码https://gitee.com/GangJust/kingosoft_api/
 */
public class QingGuoUtils {

    // *重要！当前 喜鹊儿App 的版本号
    public static String appver = "android2.5.107";
    // *重要！加密参数用到的Key值
    public static String encodeKey = "op5nb9";

    private static Map<Integer, Character> map;

    /**
     * 登录参数
     *
     * @param xxdm     学校代码
     * @param sjxh     手机型号，默认：MI 8
     * @param os       手机系统，默认：android
     * @param xtbb     android版本,默认：10
     * @param loginId  账号
     * @param password 登录密码
     * @return 组合后的参数
     */
    public static Map<String, String> getLoginParams(String xxdm, String sjxh, String os, String xtbb, String loginId, String password) {
        sjxh = sjxh == null || (sjxh.trim().equals("")) ? "MI 8" : sjxh;
        os = os == null || (os.trim().equals("")) ? "android" : os;
        xtbb = xtbb == null || (xtbb.trim().equals("")) ? "10" : xtbb;

        if (xxdm == null || xxdm.trim().equals("")) return null;
        if (loginId == null || loginId.trim().equals("")) return null;
        if (password == null || password.trim().equals("")) return null;


        //参数列表顺序需要强行如下，不能更改
        StringBuffer buffer = new StringBuffer();
        buffer.append("xxdm=").append(xxdm).append("&");
        buffer.append("sjxh=").append(sjxh).append("&");
        buffer.append("loginId=").append(loginId).append("&");
        buffer.append("sswl=").append("55555").append("&"); //默认值
        buffer.append("os=").append(os).append("&");
        buffer.append("xtbb=").append(xtbb).append("&");
        buffer.append("appver=").append(appver).append("&"); //软件版本号
        buffer.append("action=").append("getLoginInfoNew").append("&");
        buffer.append("isky=").append("1").append("&");//默认值
        buffer.append("sjbz=").append("").append("&"); //默认为空
        buffer.append("pwd=").append(password).append("&");
        buffer.append("loginmode=").append("0"); //默认值

        return encodeing(buffer.toString(), "");
    }

    public static Map<String, String> getYearListParams(QingGuoUserBean userJson){
        StringBuffer buffer = new StringBuffer();
        buffer.append("usertype=").append(userJson.getUsertype()).append("&");
        buffer.append("action=").append("getKb").append("&");
        buffer.append("step=").append("xnxq").append("&");
        buffer.append("userId=").append(userJson.getUserid()).append("&");
        buffer.append("sfid=").append(userJson.getUserid()).append("&");
        buffer.append("uuid=").append(userJson.getUuid());

        return encodeing(buffer.toString(), userJson.getToken());
    }

    /**
     * 学校列表参数
     *
     * @return 组合后的参数
     */
    public static Map<String, String> getSchoolListParams() {

        //参数列表顺序需要强行如下，不能更改
        StringBuffer buffer = new StringBuffer();
        buffer.append("appver=").append(appver).append("&");
        buffer.append("action=").append("getAgent").append("&"); //默认值
        buffer.append("xxmc=").append("");

        return encodeing(buffer.toString(), "");
    }

    /**
     * 取今日课表
     *
     * @param jsdm     未知，根据词义应该是 教室代码
     * @param week     欲获取第n周的课表
     * @param xnxq     学年学期,由 [年份+学期] 构成,例1:20200 --第一学期，列2:20201 --第二学期
     * @param bjdm     未知，根据词义应该是 班级代码
     * @return 组合后的参数
     */
    public static Map<String, String> getCourseParams(String jsdm, String bjdm, String week, String xnxq, QingGuoUserBean userJSON) {

        jsdm = (jsdm == null || jsdm.trim().equals("")) ? "" : jsdm;
        bjdm = (bjdm == null || bjdm.trim().equals("")) ? "" : bjdm;

        if (week == null || "".equals(week.trim())) return null;
        if (xnxq == null || "".equals(xnxq.trim())) return null;
        if (userJSON == null) return null;
        //if (userJSON == null) return null;

        //参数列表顺序需要强行如下，不能更改
        StringBuffer buffer = new StringBuffer();
        buffer.append("jsdm=").append(jsdm).append("&");
        buffer.append("week=").append(week).append("&");
        buffer.append("xnxq=").append(xnxq).append("&");
        buffer.append("channel=").append("jrkb").append("&"); //默认值 代表今日课表
        buffer.append("usertype=").append(userJSON.getUsertype()).append("&");
        buffer.append("action=").append("getKb").append("&"); //默认值
        buffer.append("step=").append("kbdetail_bz").append("&"); //默认值
        buffer.append("userId=").append(userJSON.getUserid()).append("&"); //由 学校代码_账号 构成
        buffer.append("bjdm=").append(bjdm).append("&");
        buffer.append("sfid=").append(userJSON.getUserid()).append("&"); //由 学校代码_账号 构成
        buffer.append("uuid=").append(userJSON.getUuid());

        return encodeing(buffer.toString(), userJSON.getToken());
    }

    /**
     * 加密参数的方法。
     *
     * @param str   如果是正确的参数列表，该参数列表中必须包含[sfid]与[uuid]。
     * @param token 默认值是00000，这个参数是用户第一次登陆后返回的。不可以省略，起码都应该传入一个 "" 空的字符串
     * @return
     */
    private static Map<String, String> encodeing(String str, String token) {
        token = ("".trim().equals(token)) ? "00000" : token;
        Map<String, String> hashMap = encodeing(str, false, "", "", token);
        hashMap.put("token", token);
        return hashMap;
    }

    /**
     * 加密参数的方法
     *
     * @param str    按规定Map散列组合后的参数列表,请参照 [encodeing(map...)] 方法
     * @param bool   如果为[true]，则token将会被使用，否则将不会被使用
     * @param userid 首次登陆后返回的参数中获取。不可以省略，起码都应该传入一个 "" 空的字符串，该参数是否使用由 [参数2 ]决定
     * @param uuid   首次登陆后返回的参数中获取。不可以省略，起码都应该传入一个 "" 空的字符串，该参数是否使用由 [参数2 ]决定
     * @param token  默认值是00000，这个参数是用户第一次登陆后返回的。不可以省略，起码都应该传入一个 "" 空的字符串，该参数是否使用由 [参数2 ]决定
     * @return
     */
    private static Map<String, String> encodeing(String str, boolean bool, String userid, String uuid, String token) {
        String key = encodeKey;

        if (bool) {
            //str = (str + "&sfid=" + u.a.userid) + "&uuid=" + u.a.uuid;
            str = (str + "&sfid=" + userid) + "&uuid=" + uuid;
        }
        if (str.indexOf("&") == 0) {
            str = str.substring(1);
        }

        //System.out.println(str);

        Map<String, String> hashMap = new HashMap();
        try {
            //ab.a("as_str=", str);
            hashMap.put("param", getParamEncode(str, key));
            hashMap.put("param2", getParam2Encode(str));
            if (bool) {
                //hashMap.put("token", u.a.token);
                hashMap.put("token", token);
                hashMap.put("appinfo", appver);
            } else {
                hashMap.put("token", "00000");
                hashMap.put("appinfo", appver);
            }
        } catch (Exception e) {
            hashMap.put("param", "error");
            hashMap.put("param2", "error");
            if (bool) {
                hashMap.put("token", "error");
                hashMap.put("appinfo", appver);
            }
        }
        return hashMap;
    }

    /**
     * param参数加密
     *
     * @param string 未加密的param参数
     * @param s      一个key值[Version]
     * @return
     */
    private static String getParamEncode(String string, String s) {
        if (string == null || "".equals(string) || s == null || "".equals(s)) {
            return string;
        }
        String s2 = "";
        int length = s.length();
        int length2 = string.length();
        int n = (int) Math.ceil(length2 * 1.0 / length);
        int n2 = (int) Math.ceil(length2 * 3.0 * 6.0 / 9.0 / 6.0);
        String string2 = "";
        String s3;
        for (int i = 0; i < n; ++i) {
            int n3 = 1;
            while (true) {
                s3 = string2;
                if (n3 > length) break;
                int n4 = i * length + n3;
                String string3 = "000" + (Integer.parseInt(toArray(string.substring(n4 - 1, n4))) + Integer.parseInt(toArray(s.substring(n3 - 1, n3))) + n2 * 6 % length);
                string2 += string3.substring(string3.length() - 3);
                if (n4 == length2) {
                    s3 = string2;
                    break;
                }
                n3++;
            }
            string2 = s3;
        }
        int n5 = 0;
        string = s2;
        while (true) {
            s = string;
            if (n5 >= string2.length()) break;
            int length3;
            if ((length3 = n5 + 9) >= string2.length()) {
                length3 = string2.length();
            }
            s = string2.substring(n5, length3);
            n5 += 9;
            s = "000000" + a(Long.parseLong(s));
            s = s.substring(s.length() - 6);
            string += s;
        }
        return s;
    }

    /**
     * param2参数加密
     *
     * @param str 未加密的param参数
     * @return 加密后的param
     */
    private static String getParam2Encode(String str) {
        String[] split = CryptoUtils.getSuperEncryptKey(str).split("");

        //可能是java的版本原因，也可能是系统的原因 linux 与 window 符号长度的原因，在手机端aide上 split[0] 应该是一个空白字符
        if (!("".equals(split[0].trim()))) {
            String[] tmp = new String[split.length + 1];
            tmp[0] = "";
            System.arraycopy(split, 0, tmp, 1, split.length);
            split = tmp;
        }

        StringBuilder str2 = new StringBuilder();
        for (int i = 0; i < split.length; i++) {
            if (!(i == 3 || i == 10 || i == 17 || i == 25)) {
                str2.append(split[i]);
            }
        }

        return CryptoUtils.getSuperEncryptKey(str2.toString());
    }

    /**
     * 该方法默认为公开的，如果有使用，请将其公开
     *
     * @param s
     * @return
     */
    private static String toArray(String s) {
        final StringBuffer sb = new StringBuffer();
        final char[] charArray = s.toCharArray();
        for (int i = 0; i < charArray.length; ++i) {
            if (i != charArray.length - 1) {
                sb.append(Integer.valueOf(charArray[i])).append(",");
            } else {
                sb.append(Integer.valueOf(charArray[i]));
            }
        }
        return sb.toString();
    }

    private static String a(long j) {
        putMap();
        String str = "";
        if (j < 0) {
            return "-" + a(Math.abs(j));
        }
        do {
            String str2 = str;
            str = (Objects.requireNonNull(map.get(((int) (j % 36))))).toString();
            if (!("".equals(str2))) {
                str = str + str2;
            }
            j /= 36;
        } while (j > 0);
        return str;
    }

    private static void putMap() {
        int i = 0;
        if (map == null) {
            map = new HashMap<>();
        }
        for (int i2 = 0; i2 < 10; i2++) {
            map.put(i2, (char) (i2 + 48));
        }
        while (i < 26) {
            map.put(i + 10, (char) (i + 97));
            i++;
        }
    }
}
